import 'dart:convert';

import 'package:mmkv/mmkv.dart';

class MMKVUtil {
  static MMKVUtil? _instance;

  MMKVUtil._internal();

  static get instance {
    _instance ??= MMKVUtil._internal();
    return _instance;
  }

  MMKV get mmkv {
    return MMKV("wan_android_flutter");
  }

  bool containsKey(String key) => mmkv.containsKey(key);

  bool getBool(String key, {bool defValue = false}) => mmkv.decodeBool(key, defaultValue: defValue);

  double getDouble(String key, {double defValue = 0.0}) =>
      mmkv.decodeDouble(key, defaultValue: defValue);

  int getInt(String key, {int defValue = 0}) => mmkv.decodeInt(key, defaultValue: defValue);

  String getString(String key, {String defValue = ''}) => mmkv.decodeString(key) ?? defValue;

  void putBool(String key, bool value) => mmkv.encodeBool(key, value);

  void putDouble(String key, double value) => mmkv.encodeDouble(key, value);

  void putInt(String key, int value) => mmkv.encodeInt(key, value);

  void putString(String key, String value) => mmkv.encodeString(key, value);

  void removeValues(String key) => mmkv.removeValue(key);

  void removeValueList(List<String> keys) => mmkv.removeValues(keys);

  void putObject(String key, Object value) => putString(key, json.encode(value));

  List<String> getAllKeys() => mmkv.allKeys;

  void clearAll() => mmkv.clearAll();

  void putArray(String key, List array) {
    String s = const JsonEncoder().convert(array);
    putString(key, s);
  }

  T? getObj<T>(String key, T Function(Map v) f, {T? defValue}) {
    Map? map = getObject(key);
    return map == null ? defValue : f(map);
  }

  Map? getObject(String key) {
    var data = getString(key);
    return (data.isEmpty) ? null : json.decode(data);
  }

  List getArrayObject(String key) {
    var data = getString(key);
    // ignore: unnecessary_null_comparison
    if (data == null) {
      return [];
    } else if (data.isEmpty) {
      return [];
    } else {
      List dataList = [];
      for (var value in const JsonDecoder().convert(data)) {
        dataList.add(value);
      }
      return dataList;
    }
  }
}